/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2022-2023. All rights reserved.
 */

package config

import (
	"fmt"

	"github.com/spf13/viper"
)

const (
	dbSQLDriver        = "mysql"
	dbMaxIdle          = 10
	dbMaxConn          = 10
	dbMaxLifeTime      = 0
	dbDefaultRowsLimit = 0
	dbServiceKey       = ""
	dbRunMode          = "vip"

	configPath1 = "./conf"
)

// NftConfig global config
type PrimConfig struct {
	DBConfig     DBConfig
	OBSConfig    OBSConfig
	BSSConfig    BSSConfig
	AdminConfig  AdminConfig
	RSAConfig    RSAConfig
	SMALConfig   SMALConfig
	COCOBSConfig COCOBSConfig
}

var conf *PrimConfig

// DBConfig define the config of connect database
type DBConfig struct {
	SQLDriver        string `json:"sql_driver"`
	MaxIdle          int    `json:"max_idle"`
	MaxConn          int    `json:"max_conn"`
	MaxLifeTime      int    `json:"max_life_time"`
	DefaultRowsLimit int    `json:"default_rows_limit"`
	DBIP             string `json:"db_ip"`
	ServiceKey       string `json:"service_key"`
	DBPort           string `json:"db_port"`
	DBName           string `json:"db_name"`
	DBUser           string `json:"db_user"`
	DBPassword       string `json:"db_password"`
	DBRunMode        string `json:"db_run_mode"`
	DBCharset        string `json:"db_charset"`
	DBLocal          string `json:"db_local"`
}
type SMALConfig struct {
	IDPMetaDataPath         string
	SPMetaDataPath          string
	SignaturePrivateKeyPath string
	SignatureCAKeyPath      string
}
type RSAConfig struct {
	PrivateKeyPath string
}
type COCOBSConfig struct {
	Endpoint   string
	AK         string
	SK         string
	BucketName string
}
type OBSConfig struct {
	Endpoint   string
	AK         string
	SK         string
	BucketName string
}
type BSSConfig struct {
	Endpoint     string
	AK           string
	SK           string
	XAccountType string
	BPID         string
}
type IVSConfig struct {
	Endpoint string
	AK       string
	SK       string
}

// AdminConfig  define the name and password of the admin
type AdminConfig struct {
	Name     string
	Password string
}

func init() {
	if err := SetConfig(); err != nil {
		fmt.Printf("Failed to init nft server conifg: %v", err)
	}
}

// SetConfig set global config by env
func SetConfig() error {
	config := viper.New()

	// for windows
	config.AddConfigPath(configPath1)
	config.SetConfigName("config")
	config.SetConfigType("ini")
	if err := config.ReadInConfig(); err != nil {
		return err
	}
	GetPrimConfigForSetConfig(config)
	return nil
}

func GetPrimConfigForSetConfig(config *viper.Viper) {
	conf = &PrimConfig{
		DBConfig{
			dbSQLDriver,
			dbMaxIdle,
			dbMaxConn,
			dbMaxLifeTime,
			dbDefaultRowsLimit,
			config.GetString("DBConfig.DB_VIP"),
			dbServiceKey,
			config.GetString("DBConfig.DB_PORT"),
			config.GetString("DBConfig.DB_NAME"),
			config.GetString("DBConfig.DB_USER"),
			config.GetString("DBConfig.DB_PWD"),
			dbRunMode,
			config.GetString("DBConfig.DB_CHARSET"),
			config.GetString("DBConfig.DB_LOCAL"),
		}, OBSConfig{
			Endpoint:   config.GetString("OBSConfig.OBS_ENDPOINT"),
			AK:         config.GetString("OBSConfig.OBS_AK"),
			SK:         config.GetString("OBSConfig.OBS_SK"),
			BucketName: config.GetString("OBSConfig.OBS_BUCKETNAME"),
		}, BSSConfig{
			Endpoint:     config.GetString("BSSConfig.BSS_ENDPOINT"),
			AK:           config.GetString("BSSConfig.BSS_AK"),
			SK:           config.GetString("BSSConfig.BSS_SK"),
			XAccountType: config.GetString("BSSConfig.BSS_XACCOUNT_TYPE"),
			BPID:         config.GetString("BSSConfig.BSS_BPID"),
		}, AdminConfig{
			Name:     config.GetString("AdminConfig.ADMIN_INIT_NAME"),
			Password: config.GetString("AdminConfig.ADMIN_INIT_PWD"),
		}, RSAConfig{
			PrivateKeyPath: config.GetString("RSAConfig.PRIVATE_KEY_PATH"),
		}, SMALConfig{
			SPMetaDataPath:          config.GetString("SAMLConfig.SP_METADATA_PATH"),
			IDPMetaDataPath:         config.GetString("SAMLConfig.IDP_METADATA_PATH"),
			SignaturePrivateKeyPath: config.GetString("SAMLConfig.SIGNATURE_PRIVATE_KEY_PATH"),
			SignatureCAKeyPath:      config.GetString("SAMLConfig.SIGNATURE_CA_KEY_PATH"),
		}, COCOBSConfig{
			Endpoint:   config.GetString("COCOBSConfig.COC_OBS_ENDPOINT"),
			AK:         config.GetString("COCOBSConfig.COC_OBS_AK"),
			SK:         config.GetString("COCOBSConfig.COC_OBS_SK"),
			BucketName: config.GetString("COCOBSConfig.COC_OBS_BUCKETNAME"),
		},
	}
}

func GetConfig() *PrimConfig {
	return conf
}
